require "libglade2"
require "SolucaoFactory"
require "Mutador"
require "Cruzador"
require 'F6' 
require 'F8' 
require 'Seletor'

class Window
	@populacao
	@mutador
	@cruzador
	@f
	
	def AG
		limite_superior = 0
		limite_inferior = 0
		if @funcao.active_text == "F6"
			limite_superior = 500
			limite_inferior = -500			
			@f = F6.new limite_inferior, limite_superior
		else
			limite_superior = 600
			limite_inferior = -600
			@f = F8.new limite_inferior, limite_superior
		end
		@s = Seletor.new(@f,@tam_pop.text.to_i)
		@f.plotar
		#p @populacao
				
		#mutacao
		@m  = Mutador.new
		operacao = Proc.new { |e|
			aux = e.valor ^ (2 ** (rand * 12))
			while(aux < e.limite_inferior or aux > e.limite_superior)
				aux = e.valor ^ (2 ** (rand * 12))
			end	
			e.valor = aux
			}
		@m.operacao = operacao
		#crossover
		@c = Cruzador.new
		cross = nil
		if @crossover.active_text == "OR"
			cross = Proc.new { |e,f|
				i = 1
				valor = (e.valor | f.valor)
				while(valor < e.limite_inferior or valor > e.limite_superior)
					valor = ((e.valor | f.valor)/i).abs
					i = i + 1
				end				
				Solucao.new((valor), e.limite_inferior, e.limite_superior)
				
			}
		elsif @crossover.active_text == "AND"
			cross = Proc.new { |e,f|
				i = 1
				valor = (e.valor | f.valor)
				while(valor < e.limite_inferior or valor > e.limite_superior)
					valor = ((e.valor | f.valor)/i).abs
					i = i + 1
				end				
				Solucao.new((valor), e.limite_inferior, e.limite_superior)
			}
		else 
			cross = Proc.new { |e,f|
				i = 1
				valor = (e.valor | f.valor)
				while(valor < e.limite_inferior or valor > e.limite_superior)
					valor = ((e.valor | f.valor)/i).abs
					i = i + 1
				end				
				Solucao.new((valor), e.limite_inferior, e.limite_superior)
			}
		end
		
		@c.oper_cross = cross		
		#fim de setar o cross
		
		factory = SolucaoFactory.new @tam_pop.text.to_i, limite_inferior, limite_superior		
		@populacao = factory.gerar_populacao		
		p @populacao
		@passos.text.to_i.times do
			@populacao = @s.seleciona(@populacao)
			@prob_cross.text.to_i.times do
				a = @populacao[(rand() * @populacao.size).abs]
				b = @populacao[(rand() * @populacao.size).abs]
				@populacao << @c.crossover(a,b)
			end
			@prob_mut.text.to_i.times do
				@m.muta @populacao[(rand() * @populacao.size).abs]
			end
		end
		@populacao = @populacao.sort_by do |e|
			@f.calcula(e.valor)
		end
		@populacao.reverse!
		@eX.text = @populacao[0].valor.to_s
		@eY.text = @f.calcula(@populacao[0].valor).to_s
	end

	def initialize(path_or_data, root = nil, domain = nil, localedir = nil, flag = GladeXML::FILE)
		@glade = GladeXML.new(path_or_data, root, domain, localedir, flag) {|handler| method(handler)}
		@go = @glade.get_widget("go")	
		@tam_pop = @glade.get_widget("tam_pop")	
		@prob_cross = @glade.get_widget("prob_cross")
		@crossover = @glade.get_widget("crossover")	
		@prob_mut = @glade.get_widget("prob_mut")
		@tipo_mut = @glade.get_widget("tipo_mut")		
		@selecao = @glade.get_widget("selecao")	    	
    	@passos = @glade.get_widget("passos")	
    	@funcao = @glade.get_widget("funcao")	
    	@window1 = @glade.get_widget("window2")    	
    	@eX = @glade.get_widget("eX")    	
    	@eY = @glade.get_widget("eY")    	
    	@go.signal_connect("clicked") do |b| 
    		self.AG
    	end
    	@window1.show 	    	
	end

end

Window.new("interface.glade");
Gtk.main
